using System.Collections;
using UnityEngine;

public class DataPacker
{
	private static uint[] powerOfTwo = new uint[32]
	{
		1u, 2u, 4u, 8u, 16u, 32u, 64u, 128u, 256u, 512u,
		1024u, 2048u, 4096u, 8192u, 16384u, 32768u, 65536u, 131072u, 262144u, 524288u,
		1048576u, 2097152u, 4194304u, 8388608u, 16777216u, 33554432u, 67108864u, 134217728u, 268435456u, 536870912u,
		1073741824u, 2147483648u
	};

	private BitArray data;

	private int maxIndex;

	private int _index;

	private int index
	{
		get
		{
			return _index;
		}
		set
		{
			if (value >= maxIndex)
			{
				BCWDebug.LogError("Переполнение!");
			}
			_index = value;
		}
	}

	public DataPacker(int size)
	{
		data = new BitArray(size * 32);
		maxIndex = size * 32;
		index = 0;
	}

	public DataPacker(int[] d)
	{
		data = new BitArray(d);
		maxIndex = data.Length;
		index = 0;
	}

	public void PackBool(bool value)
	{
		data.Set(index++, value);
	}

	public bool UnPackBool()
	{
		return data.Get(index++);
	}

	public void PackInt(int value, int max)
	{
		if (value < 0)
		{
			BCWDebug.LogError("Только положительные значения");
		}
		int numberOfBits = GetNumberOfBits(max);
		if (max < 0 || numberOfBits < 1)
		{
			BCWDebug.LogError("Неверно задано максимальное значение");
		}
		Pack(data, index, index + numberOfBits, (uint)value);
		index += numberOfBits;
	}

	public int UnPackInt(int max)
	{
		int numberOfBits = GetNumberOfBits(max);
		if (max < 0 || numberOfBits < 1)
		{
			BCWDebug.LogError("Неверно задано максимальное значение");
		}
		int result = (int)UnPack(data, index, index + numberOfBits);
		index += numberOfBits;
		return result;
	}

	public int GetInt(int number)
	{
		if (number >= maxIndex / 32)
		{
			BCWDebug.LogError("Слишком большой индекс");
		}
		int[] array = new int[maxIndex / 32];
		data.CopyTo(array, 0);
		return array[number];
	}

	private static void Pack(BitArray b, int start, int end, uint value)
	{
		for (int i = 0; i < end - start; i++)
		{
			b.Set(start + i, (value & powerOfTwo[i]) != 0);
		}
	}

	private static uint UnPack(BitArray b, int start, int end)
	{
		uint num = 0u;
		for (int i = 0; i < end - start; i++)
		{
			if (b.Get(start + i))
			{
				num += powerOfTwo[i];
			}
		}
		return num;
	}

	private static int GetNumberOfBits(int value)
	{
		for (int i = 0; i < powerOfTwo.Length; i++)
		{
			if (value < powerOfTwo[i])
			{
				return i;
			}
		}
		BCWDebug.LogError("Слишком много!");
		return 0;
	}

	public void PrintIndex()
	{
		Debug.LogError("index = " + index);
	}
}
